-- specification du paquetage dictionnaires
-- Algo, Ensimag 1A-apprentissage, PA2
-- 2009-2010, KA

with Ada.Text_Io;

generic

   -- constante de redimensionnement de la table :
   Taille_Redim: Positive;

   -- mode Debug
   Debug: Boolean;

   -- fonction de hachage :
   with function Hash(Mot: String) return Positive is <>;

package Dictionnaires is

   --------- MOTS ------------------------------------------------------------
   Lg_Max_Mot: constant Integer := 100; -- taille maximale d'un mot
   subtype Long_Mot is Integer range 0..Lg_Max_Mot;
   type Mot(Lg: Long_Mot :=0) is record
      S: String(1..Lg);
   end record;

   function Cree_Mot(S: String) return Mot;
   function Hash(M: Mot) return Natural;
   procedure Put(M: in Mot);

   -- fonction pas très utile lorsque l'on a des listes triées
   -- function Egal(Gauche, Droite: Mot) return Boolean;

   --------- DEFINITIONS -----------------------------------------------------
   Lg_Max_Def: constant Integer := 1000; -- taille maximale d'une definition
   subtype Long_Def is Integer range 0..Lg_Max_Def;
   type Definition(Lg: Long_Def :=0) is record
      S: String(1..Lg);
   end record;

   function Cree_Def(S: String) return Definition;
   procedure Put(D: in Definition);

   --------- DICTIONNAIRE ----------------------------------------------------
   type Dictionnaire is limited private;

   function Cree_Dico return Dictionnaire;
   procedure Vider(Dico: in out Dictionnaire);

   procedure Trouve(D: in Dictionnaire; M: in Mot;
                    Trouve: out Boolean; Def: out definition);
   -- Trouve = 'M est dans D'
   -- si Trouve, alors Def est la definition associee a M
   -- sinon Def n'a pas de valeur specifiee

   procedure Insere(D: in out Dictionnaire; M: in Mot; Def: in Definition);
   -- si M est dans D, cela remplace la definition de M par Def (mise a jour)
   -- sinon, M est insere dans le dictionnaire D

   procedure Supprime(D: in out Dictionnaire; M: in Mot;
                      Trouve: out Boolean; Def: out definition);
   -- Trouve = 'M est dans D'
   -- si Trouve, alors Def est la definition associee a M
   -- sinon Def n'a pas de valeur specifiee

   procedure Remplit_Dico(F: in out Ada.Text_Io.File_Type;
                          Dico: out Dictionnaire);

   -- methode pour les benchmarks, supprime tous les mots du dico
   procedure Supprime_Mots(F: in out Ada.Text_Io.File_Type;
                           Dico: in out Dictionnaire);

   -- format du fichier lu :
   -- <mot : que des lettres minuscules>
   -- <separateur> = autre chose qu'une lettre minuscule et qu'un saut
   --                de ligne
   -- <eventuellement definition>
   -- <saut de ligne>

   procedure Redim(Dico: in out Dictionnaire; Taille: in Positive);

   procedure Put(D: in Dictionnaire);
   -- affichage

   procedure Dispersion(Dico: in Dictionnaire);
   -- statistiques :
   -- affiche la longueur des listes de la table
   -- affiche la longueur moyenne des liste de la table
   -- affiche l'ecart-type par rapport a cette moyenne

   function GetTaille(Dico: in Dictionnaire) return Natural;

   function GetLength(Dico: in Dictionnaire) return Natural;

   Erreur_Dico: exception;

private

   type Table;
   type PTable is access Table;
   type Dictionnaire is record
      Taille: Natural; -- nombre de mots dans le dictionnaire
      Tab: ptable;     -- table de hachage
   end record;

   FacteurChargeInsertion : Natural := 4;
   FacteurChargeSuppression : Natural := 2;

end Dictionnaires;
